/**
 *
 */
package com.honeybees.framework.common.util;

import java.nio.charset.StandardCharsets;
import java.util.Stack;

import org.apache.commons.lang3.RandomStringUtils;

/**
 * <dl>
 * <dt><b> 标题 </b></dt>
 * <p>
 * <dd>功能描述</dd>
 * </dl>
 * <p>
 * Copyright (C) All rights reserved.
 * </p>
 *
 * @author 李远明
 * @since 2015-10-23 23:28:21
 */
public class StringUtils {

    /**
     * <DL>
     * <DT><B> 根据开始位置截取字符串，开始位置为1。 </B></DT>
     * <p>
     * 例如：
     * <DD>substring("0123456789X", 3) 返回“23456789X”</DD>
     * </DL>
     * <p>
     *
     * @param srcString 字符串
     * @param startPos  开始位置，从1开始
     * @return 截取后的字符串
     * @version 2013-09-12 15:29:50
     */
    public static String substring(String srcString, int startPos) {
        return srcString.substring(startPos - 1);
    }

    /**
     * <DL>
     * <DT><B> 根据开始位置、长度截取字符串，开始位置为1。 </B></DT>
     * <p>
     * 例如：
     * <DD>substring("0123456789X", 3, 5) 返回“23456”</DD>
     * <DD>substring("0123456789X", 1, 7) 返回“0123456”</DD>
     * <DD>substring("零一二三四五六七八九十", 1, 7) 返回“零一二三四五六”</DD>
     * </DL>
     * <p>
     *
     * @param srcString 字符串
     * @param startPos  开始位置，从1开始
     * @param length    截取长度
     * @return 截取后的字符串
     * @version 2013-09-12 15:29:50
     */
    public static String substring(String srcString, int startPos, int length) {
        char[] srcChar = srcString.toCharArray();
        char[] dest = new char[length];

        System.arraycopy(srcChar, startPos - 1, dest, 0, length);

        return new String(dest);
    }

    /**
     * <DL>
     * <DT><B> 去除字符串中多余的空格 </B></DT>
     * <p>
     * <DD>去掉一个字符串中单词间多余的空格，使得相邻两个单词间有且只有一个空格。</DD>
     * </DL>
     * <p>
     *
     * @param str 需要处理的字符串
     * @return 处理后的字符串
     * @author JacobLee
     * @version 2015-01-25 21:14:47
     */
    public static String compressSpace(String str) { // trimSpace
        String temp = String.valueOf(str.charAt(0));
        for (int i = 1; i < str.length(); i++) {
            char ch = str.charAt(i);
            if (ch == ' ') { // 如果当前字符是空格
                // 判断前一个字符是不是空格，是空格则添加，否则不添加
                if (str.charAt(i - 1) != ' ') {
                    temp += ch;
                }
            } else {
                temp += ch;
            }
        }
        return temp;
    }

    /**
     * <DL>
     * <DT><B> 判断字符串中的括号()、[]、{}是否匹配 </B></DT>
     * <p>
     * <DD>功能描述</DD>
     * </DL>
     * <p>
     *
     * @param text
     * @return
     * @author ijLee89
     * @version 2015年7月27日 下午9:06:07
     */
    public static boolean isBracketMatch(String text) {
        if (text == null || text.trim().length() == 0) {
            return false;
        }
        Stack<Character> stack = new Stack<Character>();
        char[] chars = text.toCharArray();
        for (char ch : chars) {
            if (ch == '(' || ch == '[' || ch == '{') {
                stack.push(ch); // XXX push：将元素压入栈
            } else if (ch == ')') {
                if (stack.peek() == '(') { // XXX peek：返回栈顶端的元素
                    stack.pop(); // XXX pop：移除栈顶的元素
                }
            } else if (ch == ']') {
                if (stack.peek() == '[') {
                    stack.pop();
                }
            } else if (ch == '}') {
                if (stack.peek() == '{') {
                    stack.pop();
                }
            }
        }
        return stack.isEmpty();
    }

    /**
     * <dl>
     * <dt><b> 生成指定长度的随机字符串 </b></dt>
     * <p>
     * <dd>功能描述</dd>
     * </dl>
     *
     * @param length
     * @return
     * @author 李远明
     * @version 2015年12月30日 下午2:28:35
     */
    public static String random(int length) {
        return RandomStringUtils.random(length, "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");
    }

    /**
     * <dl>
     * <dt><b> 将字符串第一个字母转换为大写 </b></dt>
     * <p>
     * <dd>功能描述</dd>
     * </dl>
     *
     * @param str
     * @return
     * @author 李远明
     * @version 2016年7月4日 下午2:59:58
     */
    public static String firstUpperCase(String str) {
        if (str == null || str.length() == 0) {
            return "";
        }
        str = str.trim();
        char[] chars = str.toCharArray();
        chars[0] = Character.toUpperCase(chars[0]);
        return new String(chars);
    }

    /**
     * <dl>
     * <dt><b> 将字符串第一个字母转换为小写 </b></dt>
     * <p>
     * <dd>功能描述</dd>
     * </dl>
     *
     * @param str
     * @return
     * @author 李远明
     * @version 2016年7月4日 下午3:01:18
     */
    public static String firstLowerCase(String str) {
        if (str == null || str.length() == 0) {
            return "";
        }
        str = str.trim();
        char[] chars = str.toCharArray();
        chars[0] = Character.toLowerCase(chars[0]);
        return new String(chars);
    }

    /**
     * <dl>
     * <dt><b> 计算字符串的字节长度 </b></dt>
     * <p>
     * <dd>Vim: strlen('...')</dd>
     * </dl>
     *
     * @param text 字符串
     * @return 字符串长度
     * @author 李远明
     * @version 2016-09-12 11:48:28 从JS中移过来的
     * @see #calcStringLength(String)
     */
    public static int calcMBytesLength(String text) {
        if (text == null || text.isEmpty()) {
            return 0;
        }
        int l = text.length(); // 字符个数
        int length = 0;
        for (int i = 0; i < l; i++) {
            char c = text.charAt(i);
            if (c < 0x007f) { // 127
                length = length + 1;
            } else if (0x0080 <= c && c <= 0x07ff) { // 128-2047：控制符和简单的特殊符号（1919）
                length += 2;
            } else if (0x0800 <= c && c <= 0xffff) { // 2048-65535：汉字和复杂的特殊符号，算三个字节（63487）
                length += 3;
            }
        }
        return length;
    }

    /**
     * 计算字符串的真实长度
     *
     * @param str 字符串
     * @return 字符串长度
     * @version 2017-04-06 09:47
     * @see #calcMBytesLength(String)
     */
    public static int calcStringLength(String str) {
        if (str == null || str.trim().isEmpty()) {
            return 0;
        }
        byte[] bytes = str.getBytes(StandardCharsets.UTF_8);
        return bytes.length;
    }

    public static void main(String[] args) {
        String str = "2017年4月1日下午6点50分，正在北京南五环外104国道上骑行的我，突然收到高中同学转发的一条微信：故乡安新变成了“首都副中心”，比肩浦东和深圳。";
        int l1 = calcMBytesLength(str);
        System.out.println(l1); // 201
        int l2 = calcStringLength(str);
        System.out.println(l2); // 201
    }
}
